#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* interface */
typedef struct product {
    void (*show)(struct product *p);
} Product;

typedef struct factory {
    Product *(*create_product)(struct factory *f);
} Factory;

typedef struct productA {
    Product product;
} ProductA;

void ProductA_show(struct product *p) { printf("product a show\n"); }

void ProductB_show(struct product *p) { printf("product b show\n"); }

typedef struct factory_a {
    Factory factory;
} FactoryA;

typedef struct factory_b {
    Factory factory;
} FactoryB;

Product *create_producta(struct factory *f)
{
    Product *product = NULL;

    product = (Product *)malloc(sizeof(Product));

    memset(product, 0, sizeof(Product));

    product->show = ProductA_show;
    return product;
}

Product *create_productb(struct factory *f)
{
    Product *product = NULL;

    product = (Product *)malloc(sizeof(Product));

    memset(product, 0, sizeof(Product));

    product->show = ProductB_show;
    return product;
}

Product *destroy_product(Product *p)
{
    if (p != NULL) {
        free(p);
    }
    return NULL;
}

int main(int argc, char **argv)
{
    FactoryA factory_a;
    factory_a.factory.create_product = create_producta;
    Product *product_a = factory_a.factory.create_product(&factory_a.factory);
    product_a->show(product_a);
    product_a = destroy_product(product_a);

    FactoryB factory_b;
    factory_b.factory.create_product = create_productb;
    Product *product_b = factory_b.factory.create_product(&factory_b.factory);
    product_b->show(product_b);
    product_b = destroy_product(product_b);

    printf("creational factory method\n");
    return 0;
}
